from pathlib import Path

import sctm

from pyfeasc.feasc import *


# 参数配置类
class Config:
	def __init__(
			self,
			path_matrix: str,
			path_maker: str,
			path_gmt: str,
			method: str = "mca",
			n_dim: int = 16,
			design: str = "~ stim",
			batch: str = "stim",
			flag: bool = True,
			p_value: float = 0.05,
			sd_weight: bool = False,
			normalize: int = 1,
	):
		"""
		SCAMP 分析配置参数类
		参数:
			path_matrix: 矩阵数据路径（如基因表达矩阵）
			path_maker: 特征标记路径
			path_gmt: GMT文件路径（基因集文件）
			method: 分析方法（默认'mca'）
			n_dim: 降维维度数（默认16）
			design: 实验设计公式（默认"~ stim"）
			batch: 批次变量名（默认"stim"）
			flag: 是否启用标志（默认True）
			p_value: 显著性阈值（默认0.05）
			sd_weight: 是否使用标准差权重（默认False）
			normalize: 归一化方式（默认1）
		"""
		self.path_matrix = path_matrix
		self.path_maker = path_maker
		self.path_gmt = path_gmt
		self.method = method
		self.n_dim = n_dim
		self.design = design
		self.batch = batch
		self.flag = flag
		self.p_value = p_value
		self.sd_weight = sd_weight
		self.normalize = normalize
	
	def to_dict(self) -> dict:
		"""将配置转换为字典格式（兼容旧代码）"""
		return {
				"path_matrix": self.path_matrix,
				"path_maker":  self.path_maker,
				"path_gmt":    self.path_gmt,
				"method":      self.method,
				"n_dim":       self.n_dim,
				"design":      self.design,
				"batch":       self.batch,
				"flag":        self.flag,
				"p_value":     self.p_value,
				"sd_weight":   self.sd_weight,
				"normalize":   self.normalize,
		}


def main():
	
	# 表达矩阵路径
	path_matrix = "../data/input/anndata/GSE96583.h5ad"
	# 标志基因集路径
	path_maker = "../data/input/marker/B-cell_marker.txt"
	# 背景基因集路径
	path_gmt = "../data/input/marker/kegg.gmt"
	
	# 设置参数
	config = Config(path_matrix, path_maker, path_gmt)
	config.method = 'mca'
	config.n_dim = 16
	config.batch = "stim"
	config.flag = True
	config.p_value = 0.05
	config.sd_weight = False
	config.normalize = 1
	
	""" 读取数据 """
	adata = sc.read_h5ad(config.path_matrix)
	adata.var_names_make_unique()
	
	""" 过滤数据 """
	sc.pp.filter_cells(adata, min_genes=200)
	# sc.pp.filter_genes(adata, min_cells=3)
	sctm.pp.filter_genes(adata, min_cutoff=0.03, expression_cutoff_99q=1)
	sc.pp.highly_variable_genes(adata, n_top_genes=3000, flavor="seurat_v3")
	adata = adata[:, adata.var.highly_variable]
	
	""" 构建基因频率矩阵 """
	gs = pd.read_table(config.path_maker, header=0).iloc[:, 0].tolist()
	gsList = {'gs': gs}
	bgList = read_gmt(config.path_gmt)
	grate = build_gene_rate(bg_list=bgList, gs_list=gsList)
	
	adata1 = adata.copy()
	"""单样本分析"""
	# 单样本降维
	adata = run_reduction(adata, method=config.method, n_dim=config.n_dim)
	# 计算活性得分
	activity_scores = calculate_activity(
			adata=adata,
			gene_rate=grate,
			method=config.method,
			n_dim=config.n_dim,
			p_value=config.p_value,
			sd_weight=config.sd_weight,
			normalize=config.normalize
	)
	filename = Path(config.path_matrix).stem
	markername = Path(config.path_matrix).stem
	activity_scores.to_csv(f'../data/output/{filename}_{config.method}_{markername}_scores.csv')
	
	"""多样本分析"""
	# 多样本整合降维 (scamp)
	adata1 = run_scamp(adata1, n_dim=config.n_dim, method=config.method, batch="stim")
	
	# 计算活性得分
	activity_scores = calculate_multi_activity(
			adata1,
			grate,
			method=config.method,
			n_dim=config.n_dim,
	)
	
	filename = Path(config.path_matrix).stem
	markername = Path(config.path_maker).stem
	activity_scores.to_csv(f'../data/output/{filename}_multi_{config.method}_{markername}_scores.csv')


if __name__ == '__main__':
	main()
